home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / wschesb1.zip / SRC / SEARCH.C < prev    next >
C/C++ Source or Header  |  1994-03-15  |  20KB  |  764 lines

  1. /*
  2.   C source for Winsock Chess
  3.   
  4.   Revision 1994-03-15
  5.   Modified by Donald Munro for use as a 2 player chess game over a 
  6.   WINSOCK layer on a TCP (or other WinSock supporting) network.
  7.   Source code and make files for MS Visual C/C++ V1.00/1.50.
  8.   February/March 1994
  9.   All GNU copyright and distribution conditions as described below and in the
  10.   file COPYING also apply to WinSock Chess.
  11.   This module is adapted from GNU Chess.
  12.  
  13.   C source for GNU CHESS
  14.  
  15.   Revision: 1990-09-30
  16.  
  17.   Modified by Daryl Baker for use in MS WINDOWS environment
  18.  
  19.   Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
  20.   Copyright (c) 1988, 1989, 1990  John Stanback
  21.  
  22.   This file is part of CHESS.
  23.  
  24.   CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
  25.   WARRANTY.  No author or distributor accepts responsibility to anyone for
  26.   the consequences of using it or for whether it serves any particular
  27.   purpose or works at all, unless he says so in writing.  Refer to the CHESS
  28.   General Public License for full details.
  29.  
  30.   Everyone is granted permission to copy, modify and redistribute CHESS, but
  31.   only under the conditions described in the CHESS General Public License.
  32.   A copy of this license is supposed to have been given to you along with
  33.   CHESS so you can know your rights and responsibilities.  It should be in a
  34.   file named COPYING.  Among other things, the copyright notice and this
  35.   notice must be preserved on all copies.
  36. */
  37.  
  38. #define NOATOM 
  39. #define NOCLIPBOARD
  40. #define NOCREATESTRUCT
  41. #define NOFONT
  42. #define NOREGION
  43. #define NOSOUND
  44. #define NOWH
  45. #define NOWINOFFSETS
  46. #define NOCOMM
  47. #define NOKANJI
  48.  
  49. #include <windows.h>
  50. #include <string.h>
  51. #include <time.h>
  52. #include <stdlib.h>
  53. #include <malloc.h>
  54. #include <stdio.h>
  55.  
  56. #include "gnuchess.h"
  57. #include "defs.h"
  58.  
  59. /*
  60.   hashbd contains a 32 bit "signature" of the board position. hashkey
  61.   contains a 16 bit code used to address the hash table. When a move is
  62.   made, XOR'ing the hashcode of moved piece on the from and to squares with
  63.   the hashbd and hashkey values keeps things current.
  64. */
  65. #define UpdateHashbd(side, piece, f, t) \
  66. {\
  67.   if ((f) >= 0)\
  68.     {\
  69.       hashbd ^= (hashcode+(side)*7*64+(piece)*64+f)->bd;\
  70.       hashkey ^= (hashcode+(side)*7*64+(piece)*64+f)->key;\
  71.     }\
  72.   if ((t) >= 0)\
  73.     {\
  74.       hashbd ^= (hashcode+(side)*7*64+(piece)*64+t)->bd;\
  75.       hashkey ^= (hashcode+(side)*7*64+(piece)*64+t)->key;\
  76.     }\
  77. }
  78.  
  79.  
  80. #if ttblsz
  81. extern unsigned long hashkey, hashbd;
  82. /*extern struct hashval hashcode[2][7][64];*/
  83. /*extern struct hashentry huge ttable[2][ttblsz];*/
  84. extern struct hashval far *hashcode;
  85. extern struct hashentry far *ttable;
  86. #endif /* ttblsz */
  87.  
  88. /*extern unsigned char history[8192];*/
  89. extern unsigned char far * history;
  90.  
  91. extern short rpthash[2][256];
  92. /*extern unsigned char nextpos[8][64][64];*/
  93. /*extern unsigned char nextdir[8][64][64];*/
  94. extern unsigned char far *nextpos;
  95. extern unsigned char far *nextdir;
  96.  
  97. extern short FROMsquare, TOsquare, Zscore, zwndw;
  98. extern unsigned short PV, Swag0, Swag1, Swag2, Swag3, Swag4;
  99. extern unsigned short killr0[maxdepth], killr1[maxdepth];
  100. extern unsigned short killr2[maxdepth], killr3[maxdepth];
  101. extern short Pscore[maxdepth], Tscore[maxdepth];
  102. extern unsigned long hashkey, hashbd;
  103. extern short ChkFlag[maxdepth], CptrFlag[maxdepth], PawnThreat[maxdepth];
  104. extern short mtl[2], pmtl[2], emtl[2], hung[2];
  105. extern short player, xwndw, rehash;
  106. extern short PieceCnt[2];
  107. extern long NodeCnt, ETnodes, EvalNodes, HashCnt, FHashCnt, HashCol;
  108. extern short HasKnight[2], HasBishop[2], HasRook[2], HasQueen[2];
  109. extern short Pindex[64];
  110.  
  111. static short _based(_segname("_CODE")) rank7[3] = {6, 1, 0};
  112. static short _based(_segname("_CODE")) kingP[3] = {4, 60, 0};
  113. static short _based(_segname("_CODE")) value[7] =
  114. {0, valueP, valueN, valueB, valueR, valueQ, valueK};
  115.  
  116. static short _based(_segname("_CODE")) sweep[8] =
  117. {false, false, false, true, true, true, false, false};
  118.  
  119. static short _based(_segname("_CODE")) ptype[2][8] = {
  120.   no_piece, pawn, knight, bishop, rook, queen, king, no_piece,
  121.   no_piece, bpawn, knight, bishop, rook, queen, king, no_piece};
  122.  
  123. static short _based(_segname("_CODE")) control[7] =
  124. {0, ctlP, ctlN, ctlB, ctlR, ctlQ, ctlK};
  125.  
  126.  
  127. void ZeroRPT (void)
  128. {
  129.   register int side, i;
  130.  
  131.   for (side = white; side <= black; side++)
  132.     for (i = 0; i < 256; i++)
  133.       rpthash[side][i] = 0;
  134. }
  135.  
  136. int castle (short int side, short int kf, short int kt, short int iop)
  137.  
  138. /* Make or Unmake a castling move. */
  139.  
  140. {
  141.   short rf, rt, t0, xside;
  142.  
  143.   xside = otherside[side];
  144.   if (kt > kf)
  145.     {
  146.       rf = kf + 3;
  147.       rt = kt - 1;
  148.     }
  149.   else
  150.     {
  151.       rf = kf - 4;
  152.       rt = kt + 1;
  153.     }
  154.   if (iop == 0)
  155.     {
  156.       if (kf != kingP[side] ||
  157.           board[kf] != king ||
  158.           board[rf] != rook ||
  159.           Mvboard[kf] != 0 ||
  160.           Mvboard[rf] != 0 ||
  161.           color[kt] != neutral ||
  162.           color[rt] != neutral ||
  163.           color[kt - 1] != neutral ||
  164.           SqAtakd (kf, xside) ||
  165.           SqAtakd (kt, xside) ||
  166.           SqAtakd (rt, xside))
  167.         return (false);
  168.     }
  169.   else
  170.     {
  171.       if (iop == 1)
  172.         {
  173.           castld[side] = true;
  174.           Mvboard[kf]++;
  175.           Mvboard[rf]++;
  176.         }
  177.       else
  178.         {
  179.           castld[side] = false;
  180.           Mvboard[kf]--;
  181.           Mvboard[rf]--;
  182.           t0 = kt;
  183.           kt = kf;
  184.           kf = t0;
  185.           t0 = rt;
  186.           rt = rf;
  187.           rf = t0;
  188.         }
  189.       board[kt] = king;
  190.       color[kt] = side;
  191.       Pindex[kt] = 0;
  192.       board[kf] = no_piece;
  193.       color[kf] = neutral;
  194.       board[rt] = rook;
  195.       color[rt] = side;
  196.       Pindex[rt] = Pindex[rf];
  197.       board[rf] = no_piece;
  198.       color[rf] = neutral;
  199.       PieceList[side][Pindex[kt]] = kt;
  200.       PieceList[side][Pindex[rt]] = rt;
  201. #if ttblsz
  202.       UpdateHashbd (side, king, kf, kt);
  203.       UpdateHashbd (side, rook, rf, rt);
  204. #endif /* ttblsz */
  205.     }
  206.   return (true);
  207. }
  208.  
  209.  
  210. static inline void
  211. EnPassant (short int xside, short int f, short int t, short int iop)
  212.  
  213. /*
  214.   Make or unmake an en passant move.
  215. */
  216.  
  217. {
  218.   register short l;
  219.  
  220.   if (t > f)
  221.     l = t - 8;
  222.   else
  223.     l = t + 8;
  224.   if (iop == 1)
  225.     {
  226.       board[l] = no_piece;
  227.       color[l] = neutral;
  228.     }
  229.   else
  230.     {
  231.       board[l] = pawn;
  232.       color[l] = xside;
  233.     }
  234.   InitializeStats ();
  235. }
  236.  
  237.  
  238. static inline void
  239. UpdatePieceList (short int side, short int sq, short int iop)
  240.  
  241. /*
  242.   Update the PieceList and Pindex arrays when a piece is captured or when a
  243.   capture is unmade.
  244. */
  245.  
  246. {
  247.   register short i;
  248.   if (iop == 1)
  249.     {
  250.       PieceCnt[side]--;
  251.       for (i = Pindex[sq]; i <= PieceCnt[side]; i++)
  252.         {
  253.           PieceList[side][i] = PieceList[side][i + 1];
  254.           Pindex[PieceList[side][i]] = i;
  255.         }
  256.     }
  257.   else
  258.     {
  259.       PieceCnt[side]++;
  260.       PieceList[side][PieceCnt[side]] = sq;
  261.       Pindex[sq] = PieceCnt[side];
  262.     }
  263. }
  264.  
  265. void
  266. ZeroTTable (void)
  267. {
  268.   register int side, i;
  269.  
  270.   if (flag.hash)
  271.     for (side = white; side <= black; side++)
  272.       for (i = 0; i < ttblsz; i++)
  273. /*        ttable[side][i].depth = 0; */
  274.         (ttable+side*2+i)->depth = 0;
  275. }
  276.  
  277. #define Link(from,to,flag,s) \
  278. {\
  279.    node->f = from; node->t = to;\
  280.      node->reply = 0;\
  281.        node->flags = flag;\
  282.          node->score = s;\
  283.            ++node;\
  284.              ++TrPnt[ply+1];\
  285.              }
  286.  
  287. static inline void
  288. LinkMove (short int ply,
  289.           short int f,
  290.           short int t,
  291.           short int flag,
  292.           short int xside)
  293.  
  294. /*
  295.   Add a move to the tree.  Assign a bonus to order the moves
  296.   as follows:
  297.   1. Principle variation
  298.   2. Capture of last moved piece
  299.   3. Other captures (major pieces first)
  300.   4. Killer moves
  301.   5. "history" killers
  302. */
  303.  
  304. {
  305.   register short s, z;
  306.   unsigned short mv;
  307.   struct leaf far *node;
  308.  
  309.   node = &Tree[TrPnt[ply + 1]];
  310.   mv = (f << 8) | t;
  311.   s = 0;
  312.   if (mv == Swag0)
  313.     s = 2000;
  314.   else if (mv == Swag1)
  315.     s = 60;
  316.   else if (mv == Swag2)
  317.     s = 50;
  318.   else if (mv == Swag3)
  319.     s = 40;
  320.   else if (mv == Swag4)
  321.     s = 30;
  322.   z = (f << 6) | t;
  323.   if (xside == white)
  324.     z |= 0x1000;
  325. /*  s += history[z]; */
  326.   s += *(history+z);
  327.   if (color[t] != neutral)
  328.     {
  329.       if (t == TOsquare)
  330.         s += 500;
  331.       s += value[board[t]] - board[f];
  332.     }
  333.   if (board[f] == pawn)
  334.     if (row (t) == 0 || row (t) == 7)
  335.       {
  336.         flag |= promote;
  337.         s += 800;
  338.         Link (f, t, flag | queen, s - 20000);
  339.         s -= 200;
  340.         Link (f, t, flag | knight, s - 20000);
  341.         s -= 50;
  342.         Link (f, t, flag | rook, s - 20000);
  343.         flag |= bishop;
  344.         s -= 50;
  345.       }
  346.     else if (row (t) == 1 || row (t) == 6)
  347.       {
  348.         flag |= pwnthrt;
  349.         s += 600;
  350.       }
  351.   Link (f, t, flag, s - 20000);
  352. }
  353.  
  354.  
  355. static inline void
  356. GenMoves (short int ply, short int sq, short int side, short int xside)
  357.  
  358. /*
  359.   Generate moves for a piece. The moves are taken from the precalulated
  360.   array nextpos/nextdir. If the board is free, next move is choosen from
  361.   nextpos else from nextdir.
  362. */
  363.  
  364. {
  365.   register short u, piece;
  366.   unsigned char far *ppos, far *pdir;
  367.  
  368.   piece = board[sq];
  369.   ppos = nextpos+ptype[side][piece]*64*64+sq*64;
  370.   pdir = nextdir+ptype[side][piece]*64*64+sq*64;
  371.   if (piece == pawn)
  372.     {
  373.       u = ppos[sq];     /* follow no captures thread */
  374.       if (color[u] == neutral)
  375.         {
  376.           LinkMove (ply, sq, u, 0, xside);
  377.           u = ppos[u];
  378.           if (color[u] == neutral)
  379.             LinkMove (ply, sq, u, 0, xside);
  380.         }
  381.       u = pdir[sq];     /* follow captures thread */
  382.       if (color[u] == xside)
  383.         LinkMove (ply, sq, u, capture, xside);
  384.       else
  385.         if (u == epsquare)
  386.           LinkMove (ply, sq, u, capture | epmask, xside);
  387.       u = pdir[u];
  388.       if (color[u] == xside)
  389.         LinkMove (ply, sq, u, capture, xside);
  390.       else
  391.         if (u == epsquare)
  392.           LinkMove (ply, sq, u, capture | epmask, xside);
  393.     }
  394.   else
  395.     {
  396.       u = ppos[sq];
  397.       do
  398.         {
  399.           if (color[u] == neutral)
  400.             {
  401.               LinkMove (ply, sq, u, 0, xside);
  402.               u = ppos[u];
  403.             }
  404.           else
  405.             {
  406.               if (color[u] == xside)
  407.                 LinkMove (ply, sq, u, capture, xside);
  408.               u = pdir[u];
  409.             }
  410.       } while (u != sq);
  411.     }
  412. }
  413.  
  414.  
  415. void
  416. MoveList (short int side, short ply)
  417.  
  418. /*
  419.   Fill the array Tree[] with all available moves for side to play. Array
  420.   TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  421. */
  422.  
  423. {
  424.   short i, xside, f;
  425.  
  426.   //ply = 2;
  427.   xside = otherside[side];
  428.   TrPnt[ply + 1] = TrPnt[ply];
  429.   if (PV == 0)
  430.     Swag0 = killr0[ply];
  431.   else
  432.     Swag0 = PV;
  433.   Swag1 = killr1[ply];
  434.   Swag2 = killr2[ply];
  435.   Swag3 = killr3[ply];
  436.   if (ply > 2)
  437.     Swag4 = killr1[ply - 2];
  438.   else
  439.     Swag4 = 0;
  440.   for (i = PieceCnt[side]; i >= 0; i--)
  441.     GenMoves (ply, PieceList[side][i], side, xside);
  442.   if (!castld[side])
  443.     {
  444.       f = PieceList[side][0];
  445.       if (castle (side, f, f + 2, 0))
  446.         {
  447.           LinkMove (ply, f, f + 2, cstlmask, xside);
  448.         }
  449.       if (castle (side, f, f - 2, 0))
  450.         {
  451.           LinkMove (ply, f, f - 2, cstlmask, xside);
  452.         }
  453.     }
  454. }
  455.  
  456.  
  457. void
  458. MakeMove (short int side,
  459.           struct leaf far * node,
  460.           short int *tempb,
  461.           short int *tempc,
  462.           short int *tempsf,
  463.           short int *tempst,
  464.           short int *INCscore)
  465.  
  466. /*
  467.   Update Arrays board[], color[], and Pindex[] to reflect the new board
  468.   position obtained after making the move pointed to by node. Also update
  469.   miscellaneous stuff that changes when a move is made.
  470. */
  471.  
  472. {
  473.   short f, t, xside, ct, cf;
  474.  
  475.   xside = otherside[side];
  476.   GameCnt++;
  477.   f = node->f;
  478.   t = node->t;
  479.   epsquare = -1;
  480.   FROMsquare = f;
  481.   TOsquare = t;
  482.   *INCscore = 0;
  483.   GameList[GameCnt].gmove = (f << 8) | t;
  484.   if (node->flags & cstlmask)
  485.     {
  486.       GameList[GameCnt].piece = no_piece;
  487.       GameList[GameCnt].color = side;
  488.       (void) castle (side, f, t, 1);
  489.     }
  490.   else
  491.     {
  492.       if (!(node->flags & capture) && (board[f] != pawn))
  493.         rpthash[side][hashkey & 0xFF]++;
  494.       *tempc = color[t];
  495.       *tempb = board[t];
  496.       *tempsf = svalue[f];
  497.       *tempst = svalue[t];
  498.       GameList[GameCnt].piece = *tempb;
  499.       GameList[GameCnt].color = *tempc;
  500.       if (*tempc != neutral)
  501.         {
  502.           UpdatePieceList (*tempc, t, 1);
  503.           if (*tempb == pawn)
  504.             --PawnCnt[*tempc][column (t)];
  505.           if (board[f] == pawn)
  506.             {
  507.               --PawnCnt[side][column (f)];
  508.               ++PawnCnt[side][column (t)];
  509.               cf = column (f);
  510.               ct = column (t);
  511.               if (PawnCnt[side][ct] > 1 + PawnCnt[side][cf])
  512.                 *INCscore -= 15;
  513.               else if (PawnCnt[side][ct] < 1 + PawnCnt[side][cf])
  514.                 *INCscore += 15;
  515.               else if (ct == 0 || ct == 7 || PawnCnt[side][ct + ct - cf] == 0)
  516.                 *INCscore -= 15;
  517.             }
  518.           mtl[xside] -= value[*tempb];
  519.           if (*tempb == pawn)
  520.             pmtl[xside] -= valueP;
  521. #if ttblsz
  522.           UpdateHashbd (xside, *tempb, -1, t);
  523. #endif /* ttblsz */
  524.           *INCscore += *tempst;
  525.           Mvboard[t]++;
  526.         }
  527.       color[t] = color[f];
  528.       board[t] = board[f];
  529.       svalue[t] = svalue[f];
  530.       Pindex[t] = Pindex[f];
  531.       PieceList[side][Pindex[t]] = t;
  532.       color[f] = neutral;
  533.       board[f] = no_piece;
  534.       if (board[t] == pawn)
  535.         if (t - f == 16)
  536.           epsquare = f + 8;
  537.         else if (f - t == 16)
  538.           epsquare = f - 8;
  539.       if (node->flags & promote)
  540.         {
  541.           board[t] = node->flags & pmask;
  542.           if (board[t] == queen)
  543.             HasQueen[side]++;
  544.           else if (board[t] == rook)
  545.             HasRook[side]++;
  546.           else if (board[t] == bishop)
  547.             HasBishop[side]++;
  548.           else if (board[t] == knight)
  549.             HasKnight[side]++;
  550.           --PawnCnt[side][column (t)];
  551.           mtl[side] += value[board[t]] - valueP;
  552.           pmtl[side] -= valueP;
  553. #if ttblsz
  554.           UpdateHashbd (side, pawn, f, -1);
  555.           UpdateHashbd (side, board[t], f, -1);
  556. #endif /* ttblsz */
  557.           *INCscore -= *tempsf;
  558.         }
  559.       if (node->flags & epmask)
  560.         EnPassant (xside, f, t, 1);
  561.       else
  562. #if ttblsz
  563.         UpdateHashbd (side, board[t], f, t);
  564. #else
  565.         /* NOOP */;     
  566. #endif /* ttblsz */
  567.       Mvboard[f]++;
  568.     }
  569. }
  570.  
  571. void
  572. UnmakeMove (short int side,
  573.             struct leaf far * node,
  574.             short int *tempb,
  575.             short int *tempc,
  576.             short int *tempsf,
  577.             short int *tempst)
  578.  
  579. /*
  580.   Take back a move.
  581. */
  582.  
  583. {
  584.   short f, t, xside;
  585.  
  586.   xside = otherside[side];
  587.   f = node->f;
  588.   t = node->t;
  589.   epsquare = -1;
  590.   GameCnt--;
  591.   if (node->flags & cstlmask)
  592.     (void) castle (side, f, t, 2);
  593.   else
  594.     {
  595.       color[f] = color[t];
  596.       board[f] = board[t];
  597.       svalue[f] = *tempsf;
  598.       Pindex[f] = Pindex[t];
  599.       PieceList[side][Pindex[f]] = f;
  600.       color[t] = *tempc;
  601.       board[t] = *tempb;
  602.       svalue[t] = *tempst;
  603.       if (node->flags & promote)
  604.         {
  605.           board[f] = pawn;
  606.           ++PawnCnt[side][column (t)];
  607.           mtl[side] += valueP - value[node->flags & pmask];
  608.           pmtl[side] += valueP;
  609. #if ttblsz
  610.           UpdateHashbd (side, (short) node->flags & pmask, -1, t);
  611.           UpdateHashbd (side, pawn, -1, t);
  612. #endif /* ttblsz */
  613.         }
  614.       if (*tempc != neutral)
  615.         {
  616.           UpdatePieceList (*tempc, t, 2);
  617.           if (*tempb == pawn)
  618.             ++PawnCnt[*tempc][column (t)];
  619.           if (board[f] == pawn)
  620.             {
  621.               --PawnCnt[side][column (t)];
  622.               ++PawnCnt[side][column (f)];
  623.             }
  624.           mtl[xside] += value[*tempb];
  625.           if (*tempb == pawn)
  626.             pmtl[xside] += valueP;
  627. #if ttblsz
  628.           UpdateHashbd (xside, *tempb, -1, t);
  629. #endif /* ttblsz */
  630.           Mvboard[t]--;
  631.         }
  632.       if (node->flags & epmask)
  633.         EnPassant (xside, f, t, 2);
  634.       else
  635. #if ttblsz
  636.         UpdateHashbd (side, board[f], f, t);
  637. #else
  638.       /* NOOP */;
  639. #endif /* ttblsz */
  640.       Mvboard[f]--;
  641.       if (!(node->flags & capture) && (board[f] != pawn))
  642.         rpthash[side][hashkey & 0xFF]--;
  643.     }
  644. }
  645.  
  646.  
  647. void
  648. InitializeStats (void)
  649.  
  650. /*
  651.   Scan thru the board seeing what's on each square. If a piece is found,
  652.   update the variables PieceCnt, PawnCnt, Pindex and PieceList. Also
  653.   determine the material for each side and set the hashkey and hashbd
  654.   variables to represent the current board position. Array
  655.   PieceList[side][indx] contains the location of all the pieces of either
  656.   side. Array Pindex[sq] contains the indx into PieceList for a given
  657.   square.
  658. */
  659.  
  660. {
  661.   short i, sq;
  662.   
  663.   epsquare = -1;
  664.   for (i = 0; i < 8; i++)
  665.     PawnCnt[white][i] = PawnCnt[black][i] = 0;
  666.   mtl[white] = mtl[black] = pmtl[white] = pmtl[black] = 0;
  667.   PieceCnt[white] = PieceCnt[black] = 0;
  668. #if ttblsz
  669.   hashbd = hashkey = 0;
  670. #endif /* ttblsz */
  671.   for (sq = 0; sq < 64; sq++)
  672.     if (color[sq] != neutral)
  673.       {
  674.         mtl[color[sq]] += value[board[sq]];
  675.         if (board[sq] == pawn)
  676.           {
  677.             pmtl[color[sq]] += valueP;
  678.             ++PawnCnt[color[sq]][column (sq)];
  679.           }
  680.         if (board[sq] == king)
  681.           Pindex[sq] = 0;
  682.         else
  683.           Pindex[sq] = ++PieceCnt[color[sq]];
  684.         PieceList[color[sq]][Pindex[sq]] = sq;
  685. #if ttblsz
  686.         hashbd ^= (hashcode+color[sq]*7*64+board[sq]*64+sq)->bd;
  687.         hashkey ^= (hashcode+color[sq]*7*64+board[sq]*64+sq)->key;
  688. #endif /* ttblsz */
  689.       }
  690. }
  691.  
  692.  
  693. int
  694. SqAtakd (short int sq, short int side)
  695.  
  696. /*
  697.   See if any piece with color 'side' ataks sq.  First check pawns then Queen,
  698.   Bishop, Rook and King and last Knight.
  699. */
  700.  
  701. {
  702.   register short u;
  703.   unsigned char far *ppos, far *pdir;
  704.   short xside;
  705.  
  706.   xside = otherside[side];
  707.   pdir = nextdir+ptype[xside][pawn]*64*64+sq*64;
  708.   u = pdir[sq];         /* follow captures thread */
  709.   if (u != sq)
  710.     {
  711.       if (board[u] == pawn && color[u] == side)
  712.         return (true);
  713.       u = pdir[u];
  714.       if (u != sq && board[u] == pawn && color[u] == side)
  715.         return (true);
  716.     }
  717.   /* king capture */
  718.   if (distance (sq, PieceList[side][0]) == 1)
  719.     return (true);
  720.   /* try a queen bishop capture */
  721.   ppos = nextpos+bishop*64*64+sq*64;
  722.   pdir = nextdir+bishop*64*64+sq*64;
  723.   u = ppos[sq];
  724.   do
  725.     {
  726.       if (color[u] == neutral)
  727.         u = ppos[u];
  728.       else
  729.         {
  730.           if (color[u] == side &&
  731.               (board[u] == queen || board[u] == bishop))
  732.             return (true);
  733.           u = pdir[u];
  734.         }
  735.   } while (u != sq);
  736.   /* try a queen rook capture */
  737.   ppos = nextpos+rook*64*64+sq*64;
  738.   pdir = nextdir+rook*64*64+sq*64;
  739.   u = ppos[sq];
  740.   do
  741.     {
  742.       if (color[u] == neutral)
  743.         u = ppos[u];
  744.       else
  745.         {
  746.           if (color[u] == side &&
  747.               (board[u] == queen || board[u] == rook))
  748.             return (true);
  749.           u = pdir[u];
  750.         }
  751.   } while (u != sq);
  752.   /* try a knight capture */
  753.   pdir = nextdir+knight*64*64+sq*64;
  754.   u = pdir[sq];
  755.   do
  756.     {
  757.       if (color[u] == side && board[u] == knight)
  758.         return (true);
  759.       u = pdir[u];
  760.   } while (u != sq);
  761.   return (false);
  762. }
  763.  
  764.